package utils;

import it.randomtower.engine.Camera;
import it.randomtower.engine.ME;
import it.randomtower.engine.World;
import it.randomtower.engine.entity.PhysicsEntity;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.HashMap;

import network.Globals;
import network.MapGlobals;
import entities.LevelFinish;
import entities.blocks.DroppingBlock;
import entities.blocks.ExplosionBlock;
import entities.blocks.GroundBlock;
import entities.blocks.HiddenBlock;
import entities.enemies.BazookaClown;
import entities.playable.PlayerAbobo;
import entities.playable.PlayerRoper;

/**
 * Liest eine .map Datei ein und bildet anhand der eingelesenen Daten ein Level
 * im Spiel und platziert die entsprechenden Entities an die richtige Stelle.
 * 
 * @author Benny
 */
public class MapManager {

	public static int curStage = 0;
	public static int playerIdentifier = 0;

	public static boolean ready = false;

	private static Parallax currentParallax = null;

	private static final String MAP_DIR = "data/maps/";

	private static final HashMap<String, Object> mapData = new HashMap<String, Object>();

	/**
	 * Liefert die HashMap mit diversen Daten dieses Levels.
	 * 
	 * @return HashMap
	 */
	public static HashMap<String, Object> getMapData() {
		return mapData;
	}

	/**
	 * Liest das angegebene Level ein und bildet die Map im aktuellen
	 * World-Objekt
	 * 
	 * @param world
	 *            - das World-Objekt, in dem das Spiel stattfindet
	 */
	public static void loadNextStage(World world) {
		ready = false;
		curStage++;

		String path = MAP_DIR + "level" + curStage + ".map";

		float curX = 0;
		float curY = 0;

		int mapWidth = 0;
		int mapHeight = 0;

		PhysicsEntity playerAbobo = new PlayerAbobo();
		PhysicsEntity playerRoper = new PlayerRoper();

		Camera cam = null;
		if (ME.attributes.get("playerOne") == Globals.ENTITIY_ABOBO)
			cam = new Camera(playerAbobo, Globals.APP_WIDTH, Globals.APP_HEIGHT);
		else
			cam = new Camera(playerRoper, Globals.APP_WIDTH, Globals.APP_HEIGHT);
		cam.setBorderY(Globals.CAMERA_STOP_FOLLOWING_BORDER);
		world.setCamera(cam);

		try {
			RandomAccessFile file = new RandomAccessFile(path, "r");

			for (int i = 0; i < file.length(); i++) {
				char curChar = (char) file.read();

				switch (curChar) {
					case '\n':
						if (mapWidth < curX)
							mapWidth = (int) curX;

						curX = -32;
						curY += 32;
						break;

					case MapGlobals.BLOCK:
						world.add(new GroundBlock(curX, curY, 32, 32));
						break;

					case MapGlobals.DROPPING_BLOCK:
						world.add(new DroppingBlock(curX, curY));
						break;

					case MapGlobals.HIDDEN_BLOCK:
						world.add(new HiddenBlock(curX, curY));
						break;

					case MapGlobals.TNT_BLOCK:
						world.add(new ExplosionBlock(curX, curY));
						break;

					case MapGlobals.PLAYER_START:
						float playerStartY = curY - 80;

						mapData.put("playerStartX", curX);
						mapData.put("playerStartY", playerStartY);

						playerAbobo.x = curX;
						playerAbobo.y = playerStartY;
						playerRoper.x = curX + 50;
						playerRoper.y = playerStartY;

						world.add(playerAbobo);
						world.add(playerRoper);
						break;

					case MapGlobals.LEVEL_FINISH:
						world.add(new LevelFinish(curX, curY - 32));
						break;

					case '1':
						world.add(new BazookaClown(curX, curY - 80));
						break;
				}

				curX += 32;
				mapHeight = (int) curY;
			}

			mapData.put("mapWidth", mapWidth);
			mapData.put("mapHeight", mapHeight);

			currentParallax = new Parallax(cam);
			currentParallax.addLayer("data/backgrounds/01_background.jpg");

			file.close();
			ready = true;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Liefert das aktuelle Parallax-Objekt der Map.
	 * 
	 * @return Parallax
	 */
	public static Parallax getCurrentParallax() {
		return currentParallax;
	}
}
